package backend.value;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

public class Register extends TarValue {
    private final String regName;

    public Register(String regName) {
        this.regName = regName;
    }


    public final static Map<String, Register> REGISTER_MAP = new HashMap<>();
    private final static Stack<Register> AVAILABLE_TEMP_REGISTERS = new Stack<>();
    private final static Stack<Register> USED_TEMP_REGISTERS = new Stack<>();

    static {
        List.of(
                "v0", "v1", "a0", "a1", "a2", "a3",
                "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                "sp", "fp", "ra"
        ).forEach(name -> {
            Register reg = new Register(name);
            REGISTER_MAP.put(name, reg);
            if (List.of("t5", "t6", "t7").contains(name)) {//if tempRegistersName
                AVAILABLE_TEMP_REGISTERS.add(reg);
            }
        });
    }

    public static Register allocTempReg() {
        if (AVAILABLE_TEMP_REGISTERS.isEmpty()) {
            return null;
        }
        var allocReg = AVAILABLE_TEMP_REGISTERS.pop();
        USED_TEMP_REGISTERS.push(allocReg);
        return allocReg;
    }

    public static void freeTempRegs() {
        USED_TEMP_REGISTERS.forEach(AVAILABLE_TEMP_REGISTERS::push);
        USED_TEMP_REGISTERS.clear();
    }

    @Override
    public String toString() {
        return "$" + regName;
    }
}
